package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.common.PageResult;
import com.itheima.common.R;
import com.itheima.entity.Employee;
import com.itheima.exception.BusinessException;
import com.itheima.mapper.EmployeeMapper;
import com.itheima.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 员工业务处理层接口实现类
 */
@Service
//类上加上事务注解
// 1.对整个类中方法进行事务控制
// 2.如果类中大多数是查询方法建议单独加上需要事务控制的方法上
@Transactional
@Slf4j
public class EmployeeServiceImpl implements EmployeeService {
    @Autowired
    private EmployeeMapper employeeMapper;

    /**
     * 后台登录功能
     *
     * @param employee
     */
    @Override
    public R<Employee> login(Employee employee, HttpSession httpSession) {
        //1.根据用户名查询emploee表 用户是否存在
        LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Employee::getUsername,employee.getUsername());//用户名条件
        Employee ey = employeeMapper.selectOne(lambdaQueryWrapper);
        //2.如果用户名不存在 返回用户名不存在提示信息
        if(ey == null){
            return R.error("登录失败:用户名不存在");
        }
        //3.如果用户名存在 用户输入的密码 跟 数据库中密码进行对比
        String userPassword = employee.getPassword();//明文123456
        String dbPassword = ey.getPassword();//密文 e10adc3949ba59abbe56e057f20f883e

        //3.1 md5介绍 将明文123456进行md5加密得到值 跟数据库中密文进行对比
       //123456 ===> e10adc3949ba59abbe56e057f20f883e 通过工具类进行md5加密
       //e10adc3949ba59abbe56e057f20f883e 通过工具类进行md5加密后密文 == 数据库密文进行对比

        //使用md5方式进行加密 需要要求密码格式尽量复杂些
        String newUserPassword = DigestUtils.md5DigestAsHex(userPassword.getBytes());
        log.debug("***用户名{}*******用户输入的密码{}********************",employee.getUsername(),userPassword);
        log.debug("**********用户输入的密码，加密后{}********************",newUserPassword);
        log.debug("**********数据查询的密码{}********************",dbPassword);
        //4.密码错误 返回密码输入错误提示信息
        if(!newUserPassword.equals(dbPassword)){
            return R.error("登录失败:密码输入错误");
        }
        //5.判断用户是否禁用 如果禁用则提示用户已被禁用无法登录
        Integer status = ey.getStatus();//1:启用 0:禁用
        if(status != 1){
            return R.error("登录失败:用户已被禁用");
        }
        //6.将员工对象放入session
        httpSession.setAttribute("employee",ey);
        return R.success(ey);//注意此处返回员工对象 页面登录成功后展示用户名
    }

    /**
     * 退出
     *
     * @param httpSession
     */
    @Override
    public void logout(HttpSession httpSession) {
        //方式一：session作用域移除employee对象 缓存并未释放
        //httpSession.removeAttribute("employee");
        //方式二：session作用域移除employee对象 缓存并释放
        httpSession.invalidate();
    }

    /**
     * 新增员工
     *
     * @param employee
     * @return
     */
    @Override
    public int save(Employee employee, Long loginUserId) {
        long id = Thread.currentThread().getId();
        log.debug("**LoginCheckFilter**线程id{}**",id);
        //根据username查询员工表
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();
        //eq 第一个参数 true false决定是否添加此条件 employee.getUsername() != null
        queryWrapper.eq(StringUtils.isNotEmpty(employee.getUsername()), Employee::getUsername, employee.getUsername());
        //如果员工username存在 抛出业务异常
        Integer count = employeeMapper.selectCount(queryWrapper);
        if(count > 0 ){
            log.debug("用户"+employee.getUsername()+"已经存在了");
            throw new BusinessException("用户"+employee.getUsername()+"已经存在了");
        }
        //新增员工账号 设置默认密码
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
        //新增员工账号 设置默认状态 1：启用 0：禁用
        employee.setStatus(1);
        //新增员工账号 创建时间
        //employee.setCreateTime(LocalDateTime.now());
        //新增员工账号 更新时间
        //employee.setUpdateTime(LocalDateTime.now());
        //新增员工账号 创建用户人
        //employee.setCreateUser(loginUserId);
        //新增员工账号 更新用户人
        //employee.setUpdateUser(loginUserId);
        return employeeMapper.insert(employee);
    }

    /**
     * 员工分页
     * 使用mybatisPlus分页
     * 1.配置分页插件
     * 2.findPage方法中使用api进行分页
     *   2.1 new Page(page,pageSize)
     *      2.1.1 添加name条件
     *   2.2 selectPage 进行分页
     *   2.3 将page对象中total records 封装到PageResult对象中
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public PageResult<Employee> findPage(Long page, Long pageSize, String name) {
        // 2.1 new Page(page,pageSize)
        Page pp = new Page(page,pageSize);
        //2.1.1 添加name条件
        LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(StringUtils.isNotEmpty(name),Employee::getName,name);//用户名
        //2.2 selectPage 进行分页
        employeeMapper.selectPage(pp,lambdaQueryWrapper);
        //2.3 将page对象中total records 封装到PageResult对象中
        log.debug("员工分页总记录数{}，当前页面数据{}",pp.getTotal(),pp.getRecords());
        return new PageResult<>(pp.getTotal(),pp.getRecords());
    }

    /**
     * 更新员工（不仅限于状态更新 员工启用 禁用）
     *
     * @param employee
     */
    @Override
    public int update(Employee employee, Long loginUserId) {
        long id = Thread.currentThread().getId();
        log.debug("**LoginCheckFilter**线程id{}**",id);
        //1.修改更新时间
        //employee.setUpdateTime(LocalDateTime.now());
        //2.修改最后更新人
        //employee.setUpdateUser(loginUserId);
        //3.调用dao更新员工信息
        return employeeMapper.updateById(employee);
    }

    /**
     * 根据员工id查询员工信息
     *
     * @param id
     */
    @Override
    public Employee findById(Long id) {
        return employeeMapper.selectById(id);
    }


}
